package snmp;

import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import java.io.IOException;

/**
 * </p>
 *
 * @author zhangsh
 * @version 1.0.0
 * @since 2019-05-18
 */
public class Snmp3Util {


    public static void main(String[] args) {
        sendSnmp();
    }

    public static void sendSnmp(){

        TransportMapping transportMapping = null;


        try {
            transportMapping = new DefaultUdpTransportMapping();
            Snmp snmp = new Snmp(transportMapping);
//            snmp.listen();

            // v3
            USM usm = new USM();
//            usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
            SecurityModels.getInstance().addSecurityModel(usm);
            snmp.listen();

            UsmUser user = new UsmUser(
                    new OctetString("nmsAdmin"),
                    AuthMD5.ID, new OctetString("nmsAuthKey"),
                    PrivDES.ID, new OctetString("nmsPrivKey"));
            //If the specified SNMP engine id is specified, this user can only be used with the specified engine ID
            //So if it's not correct, will get an error that can't find a user from the user table.
            //snmp.getUSM().addUser(new OctetString("nmsAdmin"), new OctetString("0002651100"), user);
            snmp.getUSM().addUser(new OctetString("nmsAdmin"), user);


            UserTarget target = new UserTarget();
            target.setVersion(SnmpConstants.version3);
            target.setAddress(new UdpAddress("127.0.0.1/161"));
            target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
            target.setSecurityName(new OctetString("nmsAdmin"));
            target.setTimeout(3000);	//3s
            target.setRetries(0);

            OctetString contextEngineId = new OctetString("0002651100[02]");
            ScopedPDU pdu = new ScopedPDU();
            pdu.setType(PDU.GET);
            pdu.setContextEngineID(contextEngineId);	//if not set, will be SNMP engine id
            //pdu.setContextName(contextName);  //must be same as SNMP agent

            pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.3.0")));	//sysUpTime
            pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.5.0")));	//sysName
            pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.5")));

//            snmp.send()
            ResponseEvent responseEvent = snmp.send(pdu, target);
            PDU response = responseEvent.getResponse();

            for(int i=0; i<response.size(); i++){
                System.out.println(response.get(i).toValueString());
            }


        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}
